/* Shift-JIS */
/* UTF-8 */
/********************************************************************************/
/*ソース名:                                                                     */
/*　　lib_string.c                                                              */
/*機能:                                                                         */
/*　　文字列に関連する共通関数                    　　　　　　　　　　　　　　 */
/*作成者:                                                                       */
/*　　2010-9-10 guanxiaoying（CBS）                                                 */
/********************************************************************************/
/*変更履歴:                                                                     */
/*　2010-9-10　guanxiaoying　　新規作成                                                */
/********************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <sys/stat.h>
#include <string.h>
#include <ctype.h>
#include "typedef.h"
#include "Id.h"
#include "lib_func.h"

#define MAX_DELIMITER 10
typedef struct _BREAKSTRINFO
{
	U4  u4_BreakStrId;
	PSZ pszNow;
	PSZ pszNext;
	CHAR pszDelimiter[MAX_DELIMITER];
}BREAKSTRINFO;
static BREAKSTRINFO stBreakStrInfo = { 0, NULL, "" };
/*D*/
/************************************************************************
 * 関 数 名 : libStrTrimStr
 * 機    能 : 行前後の半角スペースとタブを削除
 * 引    数 :
 * @pszLine   1行の文字列
 * 戻 り 値 :
 * 　PSZ　削除した後、残った文字列
 ************************************************************************/
PSZ   libStrSkipSpace( PSZ pszLine )
{
	register PSZ	p1;

	if( str_length(pszLine) == 0 )
	{
		return pszLine;
	}
	for( p1 = pszLine;  *p1 != '\0'; p1++ )
	{
		if( ( *p1 != ' ' ) && ( *p1 != '\t' ) )
		{
			break;
		}
	}
	return( p1 );
}
/*D*/
/************************************************************************
 * 関 数 名 : libStrTrimStr
 * 機    能 : 行前後の半角スペースとタブを削除
 * 引    数 :
 * @pszLine   1行の文字列
 * 戻 り 値 :
 * 　PSZ　削除した後、残った文字列
 ************************************************************************/
PSZ   libStrTrimStr( PSZ pszLine )
{
	register PSZ	p1;
	register PSZ	p2;

	if( str_length(pszLine) == 0 )
	{
		return pszLine;
	}
	for( p1 = pszLine;  *p1 != '\0'; p1++ )
	{
		if( ( *p1 != ' ' ) && ( *p1 != '\t' ) )
		{
			break;
		}
	}
	for( p2 = pszLine+str_length(pszLine)-1; (p2-p1) >= 0; p2-- )
	{
		if( ( *p2 != ' ' ) && ( *p2 != '\t' ) )
		{
			*(p2+1) = '\0';
			break;
		}
	}

	return( p1 );
}
/*D*/
/************************************************************************
 * 関 数 名 : libStrDelSharpComment
 * 機    能 : 行のコメント（#）を削除してから、行前後の半角スペースとタブを削除
 * 引    数 :
 * @pszLine   1行の文字列
 * @bPartlyComment  行途中のコメントが許されるかのフラグ
 * 戻 り 値 :
 * 　PSZ　削除した後、残った文字列
************************************************************************/
PSZ   libStrDelSharpComment( PSZ pszLine, BOOL bPartlyComment )
{
    PSZ pszBuf;
    register PSZ pszBuffer;

    if( pszLine == NULL )
    {
    	return NULL;
    }
    pszBuf=pszLine;
	while( ( *pszBuf ==' ') || ( *pszBuf =='\t') )
	{
		pszBuf++;
	}
	if (*pszBuf=='#')
	{
		*pszBuf = '\0';
		return pszBuf;
	}
	if (bPartlyComment == TRUE)
	{
		pszBuffer=pszBuf;
		while ( *pszBuffer != '\0' )
		{
			if (*pszBuffer == '#' )
			{
				break;
			}
			pszBuffer++;
		}
		while ( *pszBuffer != '\0' )
		{
			*pszBuffer='\0';
			pszBuffer++;
		}
	}
	return libStrTrimStr(pszBuf);
}
/*D*/
/************************************************************************
 * 関 数 名 : libStrCmpWildCard
 * 機    能 : ワイルドカード有の文字列比較
 * 　　　　　　*  任意個の任意文字
 * 　　　　　　?　1個の任意文字
 * 引    数 :
 *　 @strA  文字列A
 * 　@strB  文字列B
 * 戻 り 値 :
 * 　S4　　　0　　一致
 * 　　　　　-1　　strA < strB
 *           1    strA > strB
************************************************************************/
S4   libStrCmpWildCard( PSZ strA, PSZ strB )
{
	PSZ	p1;
	PSZ	p2;

	if( libStrSearchWildChar( strA ) )
	{
		p1 = strA;
		p2 = strB;
	}
	else
	{
		p2 = strA;
		p1 = strB;
	}
	if( p1 == NULL && p2 == NULL )
	{
		return 0;
	}
	if( p1 == NULL )
	{
		return -1;
	}
	if( p2 == NULL )
	{
		return 1;
	}
	while( *p1 != '\0' )
	{
		if ( *p1 == '?' )
		{
			if ( *p2 == '\0' )
			{
				return( 1 );
			}
		}

		if ( *p1 == '*' )
		{
			while ( *p1 == '*' )
			{
				p1 ++ ;
			}

			if ( ( *p1 == '?' ) && ( *p2 != '\0' ) )
			{
				return ( 1 ) ;
			}
			else if ( *p1 == '\0' )
			{
				return ( 0 ) ;
			}

			while ( *p1 != *p2 )
			{
				if ( *p2 == '\0' )
				{
					return ( 1 ) ;
				}

				p2 ++ ;
			}
		}
		if ( (*p1 != '*') && (*p1 != '?') )
		{
			if ( *p1 > *p2 )
			{
				return( 1 );
			}
			else if ( *p1 < *p2 )
			{
				return (-1);
			}
		}
		p1++; p2++;
	}
	if ( *p2 != '\0' )
	{
		return( -1 );
	}
	return 0;
}
/*D*/
/************************************************************************
 * 関 数 名 : libStrSearchWildChar
 * 機    能 : ワイルドカード有無を確認
 * 　　　　　　*  任意個の任意文字
 * 　　　　　　?　1個の任意文字
 * 引    数 :
 *　 @strA  文字列
 * 戻 り 値 :
 * 　TRUE　　あり
 * 　FALSE　　なし
 ************************************************************************/
BOOL libStrSearchWildChar ( PSZ pszPath )
{
	register PSZ	 p1;

	if( pszPath == NULL )
	{
		return FALSE;
	}
	for( p1 = pszPath; *p1 != '\0'; p1++ )
	{
		if ( (*p1 == '*') || (*p1 == '?') )
		{
			return( TRUE );
		}
	}
	return( FALSE );
}
/*D*/
/************************************************************************
 * 関 数 名 : libStrBreakByDelimiter
 * 機    能 : 指定された区切子(1文字)により文字列を分割する
 * 引    数 :
 *　 @strA  文字列
 * 　@strB  区切子の並び
 * 戻 り 値 :
 * 　U4  行列番号を返す。
************************************************************************/
U4   libStrBreakByDelimiter( PSZ strA, PSZ strB )
{
	register PSZ p1;
	S4 i;
	stBreakStrInfo.u4_BreakStrId++;
	stBreakStrInfo.pszNow = strA;
	stBreakStrInfo.pszNext = NULL;
	if( strB == NULL )
	{
		stBreakStrInfo.pszDelimiter[0] = '\0';
	}
	else
	{
		memset( stBreakStrInfo.pszDelimiter, 0, sizeof( stBreakStrInfo.pszDelimiter ) );
		strncpy( stBreakStrInfo.pszDelimiter, strB, MAX_DELIMITER  );
		for( p1 = strA; p1 != NULL && *p1 != '\0'; p1++ )
		{
			for( i = 0; stBreakStrInfo.pszDelimiter[i] != '\0' && i < MAX_DELIMITER; i++ )
			{
				if( *p1 == stBreakStrInfo.pszDelimiter[i] )
				{
					*p1 = '\0';
					stBreakStrInfo.pszNext = p1+1;
					if( str_length( stBreakStrInfo.pszNext ) == 0 )
					{
						stBreakStrInfo.pszNext = NULL;
					}
					break;
				}
			}
			if( *p1 == '\0' )
			{
				break;
			}
		}
	}
	return stBreakStrInfo.u4_BreakStrId;
}
/*D*/
/************************************************************************
 * 関 数 名 : libStrGetNextStr
 * 機    能 : 分割された文字列を1つずつ取得する。
 * 引    数 :
 *　 @u4_QueueNo  libStrBreakByDelimiterが返した行列番号
 * 戻 り 値 :
 * 　PSZ 　コール度、分割された文字列を順に返す。
************************************************************************/
PSZ   libStrGetNextStr( U4 u4_QueueNo )
{
	PSZ pszRes = NULL;
	register PSZ p1;
	S4 i;
	if( u4_QueueNo == stBreakStrInfo.u4_BreakStrId )
	{
		pszRes = stBreakStrInfo.pszNow;
		stBreakStrInfo.pszNow = stBreakStrInfo.pszNext;
		stBreakStrInfo.pszNext = NULL;
		for( p1 = stBreakStrInfo.pszNow; p1 != NULL && *p1 != '\0'; p1++ )
		{
			for( i = 0; stBreakStrInfo.pszDelimiter[i] != '\0' && i < MAX_DELIMITER; i++ )
			{
				if( *p1 == stBreakStrInfo.pszDelimiter[i] )
				{
					*p1 = '\0';
					stBreakStrInfo.pszNext = p1+1;
					if( str_length( stBreakStrInfo.pszNext ) == 0 )
					{
						stBreakStrInfo.pszNext = NULL;
					}
					break;
				}
			}
			if( *p1 == '\0' )
			{
				break;
			}
		}
	}
	return pszRes;
}
/*D*/
/************************************************************************
 * 関 数 名 : libStrGetSymbolLength
 * 機    能 : 引数の文字列から、シンボルとみなせる文字列の長さ
 * 引    数 :
 *　 @pszSymbol 　文字列
 * 戻 り 値 :
 * 　U4   文字数
************************************************************************/
U4   libStrGetSymbolLength( PSZ  pszSymbol )
{
	register PSZ p1;
	U4 u4Len = 0;
	if( str_length( pszSymbol ) == 0 )
	{
		return 0;
	}
	if( (*pszSymbol != '_' ) && ( !isalpha(*pszSymbol) ) )
	{
		return 0;
	}
	u4Len = 1;
	for( p1 = pszSymbol+1; p1 != '\0'; p1 ++ )
	{
		if ( *p1 == '_' || isalnum(*p1) )
		{
			u4Len++;
		}
		else
		{
			break;
		}
	}
	return u4Len;
}
/*D*/
/************************************************************************
 * 関 数 名 : libOSGetModuleFile
 * 機    能 : ツールのインストール先を取得する
 * 引    数 :
 *　 @pszBuffer 　ツールのインストール先を保存するバッファー
 *　 @lenBuf　ツールのインストール先を保存するバッファーの長さ
 * 戻 り 値 :
 * S4 正常の場合、ツールのインストール先のフォルダの文字数を返す。
 *   失敗の場合、0を返す。
************************************************************************/
S4  libOSGetModuleFile( PSZ pszToolName, PSZ pszBuffer, U4 lenBuf )
{
	struct getfilestat stFileStat;
	PSZ pszPath;
	register PSZ p;
	static CHAR szEnvPathBuf[MAX_PATH_LEN+1] = "";
	static CHAR szTempPath[OS_FULLPATH + 1 ] = "";

	if( lenBuf == 0 || pszBuffer == NULL )
	{
		return 0;
	}
	if( str_length(pszToolName) > 0 && ( 0 == _filestat( pszToolName, & stFileStat ) ) )
	{
		strncpy( pszBuffer, pszToolName, lenBuf );
		p = pszBuffer + (S4)(strlen(pszBuffer)-1);
		while( (ptrdiff_t)( p - pszBuffer ) > 0 )
		{
			if(!IS_MULTI_CHAR(*(p-1)))
			{
				if( IS_PATH_DELIMITER(*p ) )
				{
					break;
				}
			}
			p--;
		}
		if( p == pszBuffer )
		{
			if( IS_PATH_DELIMITER(*p ) )
			{
				p ++ ;
			}
		}
		*p = '\0';
		p--;
		while( (ptrdiff_t)( p - pszBuffer ) >= 0 )
		{
			if(!IS_MULTI_CHAR(*(p-1)))
			{
				if( IS_PATH_DELIMITER(*p ) )
				{
					*p = PATH_DELIMITER;
				}
			}
			p--;
		}
		if( str_length(pszBuffer) == 0 )
		{
			strcpy( pszBuffer, "./"  );
		}
		return 1;
	}
	pszPath = getenv( KEY_PATH );
	if( pszPath == NULL )
	{
		return 0;
	}
	strncpy( szEnvPathBuf, getenv( KEY_PATH ), MAX_PATH_LEN  );
	pszPath = strtok( szEnvPathBuf, ENV_PATH_DELIMITER );
	while( str_length( pszPath ) )
	{
		szTempPath[0] = '\0';
		strcpy( szTempPath, pszPath );
		szTempPath[strlen(pszPath)] = PATH_DELIMITER;
		szTempPath[strlen(pszPath)+1] ='\0';
		strcat( szTempPath, pszToolName );
		if( 0 == _filestat( szTempPath, & stFileStat ) )
		{
			pszBuffer[0] = '\0' ;
			strncpy( pszBuffer, pszPath, lenBuf );
			return 1;
		}
		pszPath = strtok( NULL, ENV_PATH_DELIMITER );
	}
	return 0;
}
/************************************************************************
 * 関 数 名 : libOSConnectPath
 * 機    能 : pszSrcはpszStandardからの相対パスである場合、pszSrcとpszStandardをくっつけて、
 *      . か  .. を削除する。
 * 引    数 :
 *　 @pszStandard 　基準
 *　 @pszSrc　相対パス
 * 戻 り 値 :


************************************************************************/
VOID  libOSConnectPath( PSZ pszStandard, PSZ pszSrc)
{
	register PSZ		pszDstDel = NULL;
	register PSZ		pszEnd = NULL;

	if( strlen( pszStandard ) < 1 )
	{
		strcpy( pszStandard, pszSrc );
		return;
	}

	pszEnd = pszSrc;
	while( *pszEnd != '\0' )
	{
		if( IS_MULTI_CHAR( *pszEnd ) )
		{
			pszEnd++;
		}
		else if( IS_PATH_DELIMITER(*pszEnd) )
		{
			*pszEnd = '\0';
			if( *pszSrc != '\0' )
			{
				if( strcmp( pszSrc, ".." ) == 0 )
				{
					pszDstDel = pszStandard + ( strlen( pszStandard ) - 1 );
					while( pszDstDel > pszStandard  )
					{
						if( !IS_MULTI_CHAR( *(pszDstDel-1) ) )
						{
							if( IS_PATH_DELIMITER(*pszDstDel))
							{
								pszDstDel--;
								continue;
							}
						}
						break;
					}
					while( pszDstDel > pszStandard )
					{
						if( !IS_MULTI_CHAR( *(pszDstDel-1) ) )
						{
							if( IS_PATH_DELIMITER(*pszDstDel))
							{
								break;
							}
						}
						else
						{
							pszDstDel--;
						}
						pszDstDel--;
					}
					if( pszDstDel == pszStandard && !IS_PATH_DELIMITER(*pszDstDel) )
					{
						*pszEnd = PATH_DELIMITER;
						strcat( pszStandard, pszSrc );
						pszSrc = pszEnd;
						break;
					}
					else
					{
						*( pszDstDel + 1 ) = '\0';
					}
					pszSrc = pszEnd + 1;
				}
				else if( strcmp( pszSrc, "." ) == 0 )
				{
					pszSrc = pszEnd + 1;
				}
				else
				{
					/* include命令により、ヘッダのパスの中に/がある可能性もあるし、ない可能性もある */
					/* 同じヘッダファイルを認識できる(パス名を比較)ために、/を\に変更する */
					if( strlen( pszStandard ) > 0 )
					{
						if( !IS_PATH_DELIMITER (*( pszStandard + strlen( pszStandard ) - 1 )))
						{
							strcat( pszStandard, PATH_DELIMITER_STR );
						}
					}
					strcat( pszStandard, pszSrc );
					strcat( pszStandard, PATH_DELIMITER_STR );
					pszSrc = pszEnd+1;
					/*break;*/
				}
			}
			else
			{

				pszSrc = pszEnd + 1;
			}
			*pszEnd = PATH_DELIMITER;
		}
		pszEnd++;
	}
	if( pszSrc < pszEnd )
	{
		strcat( pszStandard, pszSrc );
	}

}
/************************************************************************
 * 関 数 名 : libOSIsAbsolutePath
 * 機    能 : pszSrcは絶対パスかをチェックする
 * 引    数 :
 *　 @pszSrc　パス
 * 戻 り 値 :
 *  TRUE
 *  FALSE
************************************************************************/
BOOL  libOSIsAbsolutePath(  PSZ pszSrc )
{
	if( str_length( pszSrc ) < 1 )
	{
		return FALSE;
	}
#if  (__OS__ == _WINDOWS_XP ) || (  __OS__ == _WINDOWS_7  )
	if( pszSrc[0] == '\\' && pszSrc[1] == '\\' )
	{
		/* nat or net */
		return TRUE;
	}
	if ( ( isalpha(pszSrc[0]) && pszSrc[1] == ':' ) )
	{
		/* driver */
		return TRUE;
	}
	if (  IS_PATH_DELIMITER ( pszSrc[0] ) )
	{
		/* PortablePath */
		return TRUE;
	}
#elif ( __OS__ == _HP_UX_10 ) || (  __OS__ == _HP_UX_11 )
	if (  IS_PATH_DELIMITER ( pszSrc[0] ) )
	{
		/* PortablePath */
		return TRUE;
	}

#endif
	return FALSE;
}
/************************************************************************
 * 関 数 名 : libOSGetPortablePath(  PSZ pszSrc )
 * 機    能 : pszSrcは絶対パスかをチェックする
 * 引    数 :
 *　 @pszSrc　パス
************************************************************************/
VOID  libOSGetPortablePath(  PSZ pszSrc )
{
	PSZ p1;
	BOOL bChange = FALSE;

	if( str_length( pszSrc ) >= 1 )
	{
		p1 = pszSrc;
		while (  ( *p1 != '\0' ) && ( IS_PATH_DELIMITER ( p1[0] ) ) )
		{
			p1++;
		}
		bChange = TRUE;
		while( *p1 != '\0' )
		{
			if (  IS_PATH_DELIMITER ( p1[0] ) )
			{
				if( bChange)
				{
					*p1 = PATH_DELIMITER;
				}
			}
			p1 ++;
		}
	}
}
/**************end of file ************/
